package com.imay.live.view;

import android.content.Context;
import android.graphics.Matrix;
import android.util.AttributeSet;
import android.view.TextureView;

import com.imay.live.manager.PlayerManager;

/**
 * Created by chan on 2017/6/21 0021.
 */

public class IMTextureView extends TextureView {

    private int sizeW;

    private int sizeH;

    private boolean fullView;

    private int originW, originH;

    private int mVideoWidth, mVideoHeight;
    private Matrix matrix;

    public IMTextureView(Context context) {
        super(context);
    }

    public IMTextureView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int videoWidth = mVideoWidth;
        int videoHeight = mVideoHeight;

        int width = getDefaultSize(videoWidth, widthMeasureSpec);
        int height = getDefaultSize(videoHeight, heightMeasureSpec);

        int widthS = getDefaultSize(videoWidth, widthMeasureSpec);
        int heightS = getDefaultSize(videoHeight, heightMeasureSpec);


        if (PlayerManager.getShowType() == PlayerManager.SCREEN_MATCH_FULL) {
            boolean rotate = (getRotation() != 0 && getRotation() % 90 == 0 && Math.abs(getRotation()) != 180);
            if (rotate) {
                sizeW = heightMeasureSpec;
                sizeH = widthMeasureSpec;
                setMeasuredDimension(heightMeasureSpec, widthMeasureSpec);
            } else {
                sizeW = widthMeasureSpec;
                sizeH = heightMeasureSpec;
                setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
            }
            return;
        }

        if (originW == 0 || originH == 0) {
            originW = widthS;
            originH = heightS;
        }

        if (videoWidth > 0 && videoHeight > 0) {

            int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
            int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
            int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
            int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);

            if (widthSpecMode == MeasureSpec.EXACTLY && heightSpecMode == MeasureSpec.EXACTLY) {
                width = widthSpecSize;
                height = heightSpecSize;

                if (videoWidth * height < width * videoHeight) {
                    width = height * videoWidth / videoHeight;
                } else if (videoWidth * height > width * videoHeight) {
                    height = width * videoHeight / videoWidth;
                }
            } else if (widthSpecMode == MeasureSpec.EXACTLY) {
                width = widthSpecSize;
                height = width * videoHeight / videoWidth;
                if (heightSpecMode == MeasureSpec.AT_MOST && height > heightSpecSize) {
                    height = heightSpecSize;
                }
            } else if (heightSpecMode == MeasureSpec.EXACTLY) {
                height = heightSpecSize;
                width = height * videoWidth / videoHeight;
                if (widthSpecMode == MeasureSpec.AT_MOST && width > widthSpecSize) {
                    width = widthSpecSize;
                }
            } else {
                width = videoWidth;
                height = videoHeight;
                if (heightSpecMode == MeasureSpec.AT_MOST && height > heightSpecSize) {
                    height = heightSpecSize;
                    width = height * videoWidth / videoHeight;
                }
                if (widthSpecMode == MeasureSpec.AT_MOST && width > widthSpecSize) {
                    width = widthSpecSize;
                    height = width * videoHeight / videoWidth;
                }
            }
        } else {
            // no size yet, just adopt the given spec sizes
        }

        boolean rotate = (getRotation() != 0 && getRotation() % 90 == 0 && Math.abs(getRotation()) != 180);
        if (rotate) {
            if (widthS < heightS) {
                if (width > height) {
                    width = (int) (width * (float) widthS / height);
                    height = widthS;
                } else {
                    height = (int) (height * (float) width / widthS);
                    width = widthS;
                }
            } else {
                if (width > height) {
                    height = (int) (height * (float) width / widthS);
                    width = widthS;
                } else {
                    width = (int) (width * (float) widthS / height);
                    height = widthS;
                }
            }

            //如果旋转后的高度大于宽度
            if (width > height) {
                //如果视频的旋转后，width（高度）大于控件高度，需要压缩下高度
                if (originH < originW) {
                    if (width > heightS) {
                        height = (int) (height * ((float) width / heightS));
                        width = heightS;
                    }
                } else {
                    if (width > heightS) {
                        height = (int) (height / ((float) width / heightS));
                        width = heightS;
                    }
                }
            } else {
                //如果旋转后的宽度大于高度
                if (height > widthS) {
                    width = (int) (width * ((float) height / widthS));
                    height = widthS;
                }
            }
        }

        //如果设置了比例
        if (PlayerManager.getShowType() == PlayerManager.SCREEN_TYPE_16_9) {
            if (height > width) {
                width = height * 9 / 16;
            } else {
                height = width * 9 / 16;
            }
        } else if (PlayerManager.getShowType() == PlayerManager.SCREEN_TYPE_4_3) {
            if (height > width) {
                width = height * 3 / 4;
            } else {
                height = width * 3 / 4;
            }
        }

        fullView = (PlayerManager.getShowType() == PlayerManager.SCREEN_TYPE_FULL);

        //上面会调整一变全屏，这里如果要全屏裁减，就整另外一边
        if (fullView) {
            if (rotate && getRotation() != 0) {
                if (width > height) {
                    if (height < originW) {
                        width = (int) (width * ((float) originW / height));
                        height = originW;
                    } else if (width < originH) {
                        height = (int) (height * ((float) originH / width));
                        width = originH;
                    }
                } else {
                    if (width < originH) {
                        height = (int) (height * ((float) originH / width));
                        width = originH;
                    } else if (height < originW) {
                        width = (int) (width * ((float) originW / height));
                        height = originW;
                    }
                }
            } else {
                if (height > width) {
                    if (width < widthS) {
                        height = (int) (height * ((float) widthS / width));
                        width = widthS;
                    } else {
                        width = (int) (width * ((float) heightS / height));
                        height = heightS;
                    }
                } else {
                    if (height < heightS) {
                        width = (int) (width * ((float) heightS / height));
                        height = heightS;
                    } else {
                        height = (int) (height * ((float) widthS / width));
                        width = widthS;
                    }
                }
            }
        }

        sizeH = height;

        sizeW = width;

        setMeasuredDimension(width, height);
    }

    /**
     * 视频裁剪居中
     * @param videoWidth
     * @param videoHeight
     */
    public void transformVideo(int videoWidth, int videoHeight) {
        if (getHeight() == 0 || getWidth() == 0) {
            return;
        }
        float sx = (float) getWidth() / (float) videoWidth;
        float sy = (float) getHeight() / (float) videoHeight;

        float maxScale = Math.max(sx, sy);
        if (this.matrix == null) {
            matrix = new Matrix();
        } else {
            matrix.reset();
        }

        //第2步:把视频区移动到View区,使两者中心点重合.
        matrix.preTranslate((getWidth() - videoWidth) / 2, (getHeight() - videoHeight) / 2);

        //第1步:因为默认视频是fitXY的形式显示的,所以首先要缩放还原回来.
        matrix.preScale(videoWidth / (float) getWidth(), videoHeight / (float) getHeight());

        //第3步,等比例放大或缩小,直到视频区的一边超过View一边, 另一边与View的另一边相等. 因为超过的部分超出了View的范围,所以是不会显示的,相当于裁剪了.
        matrix.postScale(maxScale, maxScale, getWidth() / 2, getHeight() / 2);//后两个参数坐标是以整个View的坐标系以参考的


        setTransform(matrix);
        postInvalidate();
    }

    public int getSizeH() {
        return sizeH;
    }

    public int getSizeW() {
        return sizeW;
    }

    public void setVideoWidth(int mVideoWidth) {
        this.mVideoWidth = mVideoWidth;
    }

    public void setVideoHeight(int mVideoHeight) {
        this.mVideoHeight = mVideoHeight;
    }
}
